# encoding: UTF-8

'''
本文件中包含的是CTA模块的回测引擎，回测引擎的API和CTA引擎一致，
可以使用和实盘相同的代码进行回测。
'''

from datetime import datetime, timedelta
from collections import OrderedDict
import json
import pymongo

from base.ctaBase import *
from strategy.ctaSetting import *
from engine.ctaBacktesting import BacktestingEngine

from ctaCondiction import CondictionStrategy
from condiction.condictions import *
from database.mysqlbusiness import *

def runBacktest(symbol, period, conds):
    
    # 创建回测引擎
    engine = BacktestingEngine()

    # 设置引擎的回测模式为K线
    engine.setBacktestingMode(engine.TICK_MODE)

    # 设置滑点
    engine.setSlippage(0.5)     # 铁矿石2跳

    # 设置回测用的数据起始日期
    engine.setStartDate('20150201')

    # 载入历史数据到引擎中
    #engine.loadHistoryData(TICK_DB_NAME, 'I1605')
    engine.loadHistoryData(TICK_DB_NAME, symbol)

    # 在引擎中创建策略对象
    #engine.initStrategy(CondictionStrategy, {'vtSymbol' : 'I1605', 'period': 1})
    engine.initStrategy(CondictionStrategy, {'vtSymbol': symbol, 'period': period})
    #增加信号条件
    #RSIC = RSICondiction()
    #RSIC.setParam({'RSI-PERIOD': 14, 'RSI-BUY': 30, 'RSI-SELL': 70})
    #engine.strategy.addCondiction(RSIC)
    #STOC = STOCondiction()
    #STOC.setParam({'STO-PERIOD': 5, 'STO-KPERIOD': 3, 'STO-DPERIOD': 3, 'STO-BUY': 20, 'STO-SELL': 80})
    #engine.strategy.addCondiction(STOC)
    #MALineTradeC = MALineTradeCondiction()
    #MALineTradeC.setParam({'MALine-PERIOD': 60})
    #engine.strategy.addCondiction(MALineTradeC)

    for name, con in conds.items():
        engine.strategy.addCondiction(con)

    print u"开始策略CondictionStrategy, symbol=%s, condictions=[%s, %s]"
    engine.runBacktesting()

    engine.showBacktestingResult()

def YieldParam(cond):
    varialbes = loadVariableParam(cond)
    paramYield = {}
    for name, start, end, internal in varialbes:
        paramYield[name]= YieldVariable(start, end, internal)
    res = []
    #print paramYield
    for k,v in paramYield.items():
        #print '\n'
        #print [{k:i} for i in v]
        #print res
        res = YieldList(res, [{k:i} for i in v])
    #print res
    return res

def YieldVariable(start, end, internal):
    for i in range(start, end, internal):
        yield i

def YieldList(listA, listB):
    res = []

    for b in listB:
        data = {}
        data[b.items()[0][0]] = b.items()[0][1]
        if len(listA)==0:
            res.append(data.copy())
        for a in listA:
            data.update(a)
            res.append(data.copy())
    #print res
    return res

    

if __name__ == '__main__':

    #获取行情列表
    code = [i[0] for i in loadTickCode()]
    #获取趋势指标
    trend = [i[0] for i in loadCondiction(1)]
    trendParam = {}
    print code
    print trend
    print overcome
    for index in trend:
        trendParam[index] = YieldParam(index)
        print index

    #获取突破指标
    overcome = [i[0] for i in loadCondiction(2)]
    overcomeParam = {}
    for index in overcome:
        overcomeParam[index] = YieldParam(index)

    #YieldParam(trend[0])
    for symbol in code:
        """行情代码穷举"""
        for period in range(1, 100):
            """周期穷举"""
            for trendName in trend:
                """趋势指标穷举"""
                trendClz = eval(trendName+"()")
                trendClzParam = trendParam[trendName]
                for param in trendClzParam:
                    trendClz.setParam(trendClzParam)
                    for overcomeName in overcome:
                        overcomeClz = eval(overcomeName+"()")
                        overcomeClzParam = overcomeParam[overcomeName]
                        for par in overcomeClzParam:
                            overcomeClz.setParam(par)
                            print "New Param"
                            runBacktest(symbol, period, [trendClz, overcomeClz])


                
    #YieldParam('RSICondiction')
    #runBacktest()
    #print YieldList([],[{'b':2}, {'b':3}])
    #print YieldList([{'b':2}, {'b':3}], [{'a':1}, {'c':2}, {'d':4}])

